using Commons.Models.Capabilities;
using Commons.Models.Definitions;
using System;
using System.Collections.Generic;

namespace Commons.Models.Locks
{
	[Serializable]
	public class Lock : ICapable
	{
		public const int PublicId = -1;
		public int Id { get; private set; }
		public List<IUnlockCondition> UnlockConditions { get; protected set; }

		private CapableDelegate<Lock> capableDelegate;

		public Lock(int id)
		{
			this.Id = id;
			this.UnlockConditions = new List<IUnlockCondition>();
			this.capableDelegate = new CapableDelegate<Lock>(this);
		}

		public T GetUnlockCondition<T>() where T : IUnlockCondition
		{
			foreach (IUnlockCondition condition in UnlockConditions)
			{
				if (condition is T)
				{
					return (T) condition;
				}
			}

			return default(T);
		}

		public void AddUnlockCondition(IUnlockCondition condition)
		{
			UnlockConditions.Add(condition);
		}

		public bool HasCapability<T>() where T : ICapability
		{
			return capableDelegate.HasCapability<T>();
		}

		public T GetCapability<T>() where T : ICapability
		{
			return capableDelegate.GetCapability<T>();
		}

		public void AddCapability(ICapability capability)
		{
			capableDelegate.AddCapability(capability);
		}

		public IEnumerable<ICapability> GetCapabilities()
		{
			return capableDelegate.GetCapabilities();
		}

		public bool HasCapability(Type type)
		{
			return capableDelegate.HasCapability(type);
		}

		public object GetCapability(Type type)
		{
			return capableDelegate.GetCapability(type);
		}

		public override string ToString ()
		{
			return string.Format ("[Lock: Id={0}, UnlockConditionsLength={1}]", Id, UnlockConditions.Count);
		}
	}
}
